--- title: "04-方法重载和方法重写" created: 2025-12-02 tags: - Java --- # 方法重载和方法重写 ### **Java 方法重载与方法重写的区别** **方法重载(Overloading)** 和 **方法重写(Overriding)** 是 Java 中的两种常见概念,它们看似相似,但在行为和实现上有很大的区别。 #### **1. 方法重载(Overloading)** 方法重载是在同一个类中,允许有多个同名方法,只要它们的参数列表不同(参数个数、类型或顺序不同)。重载主要是通过方法的签名来区分,签名包括方法的名称和参数列表,但不包括返回类型。 - **发生地点**:在同一个类中。 - **参数列表**:方法重载要求方法的参数个数、类型或顺序不同,返回类型无关。 - **返回类型**:可以不同。 - **访问修饰符**:不受限制,方法重载的访问修饰符可以是任何类型。 - **静态和非静态**:可以是静态方法或非静态方法。 - **异常**:方法的异常可以不同。 #### **重载示例:** ```java public class OverloadingExample { // 重载方法:参数数量不同 public void print(int a) { System.out.println("Printing int: " + a); } // 重载方法:参数类型不同 public void print(String a) { System.out.println("Printing String: " + a); } // 重载方法:参数类型和数量不同 public void print(int a, int b) { System.out.println("Printing two ints: " + a + ", " + b); } } ``` 在上述代码中,`print()` 方法有三种重载形式,参数类型和数量不同,但它们的返回类型是相同的。 --- #### **2. 方法重写(Overriding)** 方法重写是指子类在继承父类时,重新定义父类的方法(方法名、参数列表必须相同),以提供特定的实现。方法重写主要用于实现**多态性**,即同一方法在不同对象上的行为不同。 - **发生地点**:在继承关系的子类和父类之间。 - **参数列表**:必须相同,不能改变参数列表。 - **返回类型**:必须与父类方法的返回类型相同,或者是父类返回类型的子类(协变返回类型)。 - **访问修饰符**:子类方法的访问修饰符不能比父类更严格,通常可以是相同或更宽泛(如父类为 `protected`,子类可以是 `public`)。 - **静态和非静态**:只能重写非静态方法,静态方法不能被重写(但静态方法可以被隐藏)。 - **异常**:子类的异常不能抛出比父类更多的异常,可以抛出更少的或相同类型的异常。 #### **重写示例:** ```java class Parent { public void display() { System.out.println("Parent display"); } } class Child extends Parent { @Override public void display() { System.out.println("Child display"); } } public class OverridingExample { public static void main(String[] args) { Parent obj = new Child(); obj.display(); // 输出 "Child display" } } ``` 在上面的代码中,`Child` 类重写了 `Parent` 类的 `display()` 方法。当 `Parent` 类型的引用指向 `Child` 对象时,调用的是子类 `Child` 中的 `display()` 方法,这实现了**运行时多态性**。 --- ### **方法重载与方法重写的区别总结** | **区别** | **方法重载(Overloading)** | **方法重写(Overriding)** | | --- | --- | --- | | **发生的场所** | 在同一个类中 | 在继承关系的子类和父类之间 | | **参数列表** | 必须不同(参数的个数、类型或顺序不同) | 必须相同,不能改变参数列表 | | **返回类型** | 可以不同 | 必须与父类方法的返回类型相同,或是父类返回类型的子类(协变返回类型) | | **访问修饰符** | 不受访问修饰符影响 | 子类方法的访问修饰符不能比父类更严格 | | **静态和非静态** | 可以是静态方法或非静态方法 | 只能重写非静态方法,静态方法不能被重写(静态方法可以被隐藏) | | **异常处理** | 方法的异常处理可以不同 | 子类的异常不能抛出比父类更多的异常(可以抛出更少的或相同类型的异常) | ### **扩展知识** #### **方法重载注意点** - **签名**:方法重载是根据方法的**签名**来区分的,而签名包括方法名和参数列表,但不包括返回类型。 - **常见应用**:重载通常用于提供同一操作的不同实现,如处理不同类型的输入数据,或者对构造函数进行重载以创建对象的不同方式。 #### **方法重写注意点** - **@Override 注解**:使用 `@Override` 注解可以帮助编译器检查方法是否正确地重写了父类的方法,避免错误地重写或没有重写。 - **多态性**:方法重写通常与**多态性**结合使用,通过父类类型的引用指向子类对象,实现动态方法调用(运行时多态)。 --- ### **总结** - **方法重载** 允许在同一个类中定义多个方法,方法名相同但参数列表不同,用于提供相同操作的不同实现。 - **方法重写** 允许子类重新定义从父类继承来的方法,以提供新的实现,通常用于实现多态性。 - **重载** 关注方法签名的变化,而 **重写** 关注继承关系中的方法实现的修改。 ## 相关笔记 重写/重载的完整规则(两同两小一大、@Override、常见坑)见 [[04-重写与重载|重写与重载]];多态绑定时机见 [[05-编译时多态和运行时多态|编译时多态和运行时多态]]。 --- ⬅️ [[03-接口多实现|接口多实现]] 🏠 [[00-Java|00-Java]] ➡️ [[05-编译时多态和运行时多态|编译时多态和运行时多态]]